import {
  AppContext,
  Component,
  ComponentInternalInstance,
  ComponentPublicInstance,
  h,
  render,
  VNode
} from "vue";
// eslint-disable-next-line prettier/prettier
import type { ModalProps, ModalFuncProps } from "ant-design-vue";
import { cp } from "@/untils/mydialog";

let vms = {} as ComponentPublicInstance<customProps>;
type customProps = ModalProps | ModalFuncProps;
export interface CommandComponent {
  (options: customProps): VNode;
  close?: () => void;
}

const getAppendToElement = (props: customProps): HTMLElement => {
  let getContainer: HTMLElement | null = document.body;
  if (props.getContainer) {
    if (typeof props.getContainer === 'string') {
      getContainer = document.querySelector<HTMLElement>(props.getContainer);
    }
    if (props.getContainer instanceof HTMLElement) {
      getContainer = props.getContainer;
    }
    if (!(getContainer instanceof HTMLElement)) {
      getContainer = document.body;
    }
  }
  return getContainer;
};

const initInstance = <T extends Component>(
  Component: T,
  props: customProps,
  container: HTMLElement,
  appContext: AppContext | null = null,
) => {
  const customComponent = cp(Component, props);
  const vNode = h(customComponent);
  vNode.appContext = appContext;
  render(vNode, container);

  getAppendToElement(props).appendChild(container);
  return vNode;
};

export const useCommandComponent = <T extends Component>(
  Component: T,
  currentInstance: ComponentInternalInstance | null,
): CommandComponent => {
  const appContext = currentInstance?.appContext;
  console.log('appContext', appContext);
  // 补丁：Component中获取当前组件树的provides
  if (appContext) {
    const currentProvides = (currentInstance as any)?.provides;
    Reflect.set(appContext, 'provides', {
      ...appContext.provides,
      ...currentProvides,
    });
  }

  const container = document.createElement('div');

  const close = () => {
    vms.visible = false;
  };

  const CommandComponent = (options: customProps): VNode => {
    if (typeof options.onCancel  !== 'function') {
      options.onCancel = close;
    } else {
      const originOnClose = options.onCancel ;
      options.onCancel  = (e: MouseEvent) => {
        originOnClose?.(e);
        close();
      };
    }
    const vNode = initInstance<T>(Component, options, container, appContext);
    vms = vNode.component?.proxy as ComponentPublicInstance<customProps>;
    return vNode;
  };

  CommandComponent.close = close;

  return CommandComponent;
};

export default useCommandComponent;
